home *** CD-ROM | disk | FTP | other *** search
/ Amiga Plus 2004 #2 / Amiga Plus CD - 2004 - No. 02.iso / AmiSoft / Dev / e / q-device_src.lha / Q-Device / Q-Device.e < prev    next >
Encoding:
Text File  |  2003-12-17  |  71.3 KB  |  1,470 lines

  1. OPT PREPROCESS, OSVERSION=37
  2.  
  3. /*
  4.     Program:     Q-Device
  5.     Version:     V0.3
  6.     Author:      Ian Chapman
  7.     Description: A low-level SCSI query, command and diagnostic tool.
  8.  
  9.     LICENSE: Permission is granted to use this source code in whole or in part,
  10.              providing that the author (Ian Chapman) is credited in your project
  11.              in either the documentation, or the program itself. This applies to
  12.              both free and commercial software. In the case of commerical
  13.              software (including ShareWare), I am entitled to a free, fully
  14.              functional copy of the software.
  15.  
  16.              NO WARRANTY EITHER EXPRESSED OR IMPLIED AS TO THE FITNESS OF THIS
  17.              CODE FOR ANY PURPOSE. ALL USE IS ENTIRELY AND WHOLLY AT YOUR OWN
  18.              RISK
  19. */
  20.  
  21. MODULE  'exec/ports',
  22.         'exec/io',
  23.         'exec/execbase',
  24.         'exec/lists',
  25.         'exec/nodes',
  26.         'amigalib/io',
  27.         'devices/scsidisk',
  28.         'muimaster',
  29.         'mui/betterstring_mcc',
  30.         'libraries/mui',
  31.         'libraries/gadtools',
  32.         'amigalib/boopsi',
  33.         'intuition/classusr',
  34.         'utility/tagitem',
  35.         'utility/hooks',
  36.         'tools/installhook',
  37.         '*opcodes',
  38.         '*params',
  39.         '*headers'
  40.  
  41. CONST BUFFSIZE=254
  42. ENUM ID_INQUIRE=1, ID_EJECT, ID_INSERT, ID_LOCK, ID_UNLOCK, ID_CAPACITY, ID_TESTREADY, ID_READTOC,
  43.      ID_POWERUP, ID_POWERDOWN, ID_PROBE, ID_ABOUT, ID_MUIABOUT, ID_ICONIFY, ID_MUISET, ID_DIAGNOSTIC,
  44.      ID_DOUBLECLICK, ID_MODESENSE, ID_LOG_SUPPORT, ID_LOG_WRITE, ID_LOG_READ, ID_LOG_REVREAD,
  45.      ID_LOG_VERIFY, ID_LOG_NMERRORS, ID_LOG_BUFFER, ID_LOG_EVENTS, ID_PREFS, ID_SAVEPREF, ID_USEPREF,
  46.      ID_CANCELPREF
  47.  
  48. ENUM NORMAL=0, ERR_MP=1, ERR_IOR, ERR_DEVICE, ERR_NOMUI, ERR_NOAPP
  49. ENUM OBID_DRIVER=1, OBID_UNIT, OBID_PROBEFROM, OBID_PROBETO
  50.  
  51. OBJECT listentry -> Entries for the listview
  52. field
  53. value
  54. driver
  55. unit
  56. ENDOBJECT
  57.  
  58. DEF app, mui_output_lst, mui_output_lv, mui_status_tb, mui_device_tb,
  59.     mui_unit_tb, displayhook:hook, constructhook:hook, destructhook:hook,
  60.     devicelist[50]:ARRAY OF LONG, execobject:PTR TO execbase, inquiry_type=TRUE,
  61.     global_devtype=0
  62.  
  63. PROC main() HANDLE
  64. DEF signal, result, running=TRUE, driver[80]:STRING, unit[4]:STRING, probefrom[4]:STRING,
  65.     probeto[4]:STRING, mui_probefrom_tb, mui_probeto_tb,
  66.     mui_main_win, mui_prefs_win, mui_inquire_but, mui_eject_but, mui_insert_but,
  67.     mui_lock_but, mui_unlock_but, mui_capacity_but, mui_testready_but, mui_readtoc_but,
  68.     mui_powerup_but, mui_powerdown_but, mui_probe_but,
  69.     mui_diagnostic_but,  mui_modesense_but, mui_diagnostic_cyc, mui_prefsave_but,
  70.     mui_prefuse_but, mui_prefcancel_but, mui_logsupport_but, mui_logwrite_but, mui_logread_but,
  71.     mui_logrevread_but, mui_logverify_but, mui_lognmerrors_but, mui_logbuffer_but, mui_logevents_but,
  72.     menu, diagflag=0, i
  73.  
  74.     grab_devices()
  75.     menu:= [ NM_TITLE, 0, 'Project', 0, 0, 0, 0,
  76.              NM_ITEM,  0, 'About...', '?', 0, 0, ID_ABOUT,
  77.              NM_ITEM,  0, 'About MUI...', 0, 0, 0, ID_MUIABOUT,
  78.              NM_ITEM,  0, NM_BARLABEL, 0, 0, 0, 0,
  79.              NM_ITEM,  0, 'Iconify', 'I', 0, 0, ID_ICONIFY,
  80.              NM_ITEM,  0, 'Quit', 'Q', 0, 0, MUIV_Application_ReturnID_Quit,
  81.              NM_TITLE, 0, 'Query', 0, 0, 0, 0,
  82.              NM_ITEM,  0, 'Probe', 0, 0, 0, ID_PROBE,
  83.              NM_ITEM,  0, 'Full Inquiry', 0, 0, 0, ID_INQUIRE,
  84.              NM_ITEM,  0, 'Capacity', 0, 0, 0, ID_CAPACITY,
  85.              NM_ITEM,  0, 'Test Ready', 0, 0, 0, ID_TESTREADY,
  86.              NM_ITEM,  0, 'Device Parameters', 0, 0, 0, ID_MODESENSE,
  87.              NM_ITEM,  0, 'Read TOC', 0, 0, 0, ID_READTOC,
  88.              NM_ITEM,  0, NM_BARLABEL, 0, 0, 0, 0,
  89.              NM_ITEM,  0, 'Scan Firmware Logs', 0, 0, 0, ID_LOG_SUPPORT,
  90.              NM_ITEM,  0, 'Write Errors', 0, 0, 0, ID_LOG_WRITE,
  91.              NM_ITEM,  0, 'Read Errors', 0, 0, 0, ID_LOG_READ,
  92.              NM_ITEM,  0, 'Rev. Read Errors', 0, 0, 0, ID_LOG_REVREAD,
  93.              NM_ITEM,  0, 'Verify Errors', 0, 0, 0, ID_LOG_VERIFY,
  94.              NM_ITEM,  0, 'Non Medium Errors', 0, 0, 0, ID_LOG_NMERRORS,
  95.              NM_TITLE, 0, 'Control', 0, 0, 0, 0,
  96.              NM_ITEM,  0, 'Power Up', 0, 0, 0, ID_POWERUP,
  97.              NM_ITEM,  0, 'Power Down', 0, 0, 0, ID_POWERDOWN,
  98.              NM_ITEM,  0, 'Lock', 0, 0, 0, ID_LOCK,
  99.              NM_ITEM,  0, 'UnLock', 0, 0, 0, ID_UNLOCK,
  100.              NM_ITEM,  0, 'Insert', 0, 0, 0, ID_INSERT,
  101.              NM_ITEM,  0, 'Eject', 0, 0, 0, ID_EJECT,
  102.              NM_TITLE, 0, 'Diagnostic', 0, 0, 0, 0,
  103.              NM_ITEM,  0, 'Unit Self Test', 0, 0, 0, ID_DIAGNOSTIC,
  104.              NM_TITLE, 0, 'Settings', 0, 0, 0, 0,
  105.              NM_ITEM,  0, 'MUI Settings', 0, 0, 0, ID_MUISET,
  106.              NM_ITEM,  0, 'Preferences', 'P', 0, 0, ID_PREFS,
  107.              NM_ITEM,  0, NM_BARLABEL, 0, 0, 0, 0,
  108.              NM_ITEM,  0, 'Save Preferences', 0, 0, 0, ID_SAVEPREF,
  109.              NM_END,   0, NIL, 0, 0, 0, 0]:newmenu
  110.     
  111.     IF (muimasterbase:=OpenLibrary('muimaster.library', 19))=NIL THEN Raise(ERR_NOMUI)
  112.     installhook(displayhook, {disp})
  113.     installhook(constructhook, {construct})
  114.     installhook(destructhook, {destruct})
  115.  
  116.     mui_output_lv:=ListviewObject,
  117.                     MUIA_Listview_Input, MUI_TRUE,
  118.                     MUIA_CycleChain, 1,
  119.                     MUIA_Listview_List, mui_output_lst:=ListObject,
  120.                         ReadListFrame,
  121.                             MUIA_List_Title, MUI_TRUE,
  122.                             MUIA_List_Format, 'BAR,',
  123.                             MUIA_List_DisplayHook, displayhook,
  124.                             MUIA_List_ConstructHook, constructhook, ->MUIV_List_ConstructHook_String,
  125.                             MUIA_List_DestructHook, destructhook, ->MUIV_List_DestructHook_String,
  126.                             MUIA_ShortHelp, 'Information and diagnostic output',
  127.                         End, -> ReadListFrame
  128.                     End ->Listviewobject
  129.  
  130.     mui_inquire_but:=make_button('Full Inquiry', 'Display full inquiry information')
  131.     mui_eject_but:=make_button('Eject', 'Attempt to eject media')
  132.     mui_insert_but:=make_button('Insert', 'Attempt to insert media')
  133.     mui_lock_but:=make_button('Lock', 'Prevent media from being removed')
  134.     mui_unlock_but:=make_button('UnLock', 'Allow media to be removed')
  135.     mui_capacity_but:=make_button('Capacity', 'Show device capacity')
  136.     mui_testready_but:=make_button('Test Ready', 'Test if unit is ready')
  137.     mui_readtoc_but:=make_button('Read TOC', 'Show CD Table of Contents')
  138.     mui_powerup_but:=make_button('Power Up', 'Attempt to spin-up the device')
  139.     mui_powerdown_but:=make_button('Power Down', 'Attempt to spin-down the device')
  140.     mui_probe_but:=make_button('Probe', 'Probe driver for attached devices')
  141.     mui_diagnostic_but:=make_button('Start Self Test', 'Instruct the device to perform a self test')
  142.     mui_modesense_but:=make_button('Device Parameters', 'Return information about the device\as parameters and specs')
  143.     mui_logsupport_but:=make_button('Scan Firmware Logs', 'Lists the known log types in the device\as firmware')
  144.     mui_logwrite_but:=make_button('Write Errors', 'Show the Write Error log for the device')
  145.     mui_logread_but:=make_button('Read Errors', 'Show the Read Error log for the device')
  146.     mui_logrevread_but:=make_button('Rev. Read Errors', 'Show the Reverse Read Error log for the device')
  147.     mui_logverify_but:=make_button('Verify Errors', 'Show the Verify Error log for the device')
  148.     mui_lognmerrors_but:=make_button('Non Medium Errors', 'Show the log of errors not related to media')
  149.     mui_logbuffer_but:=make_button('Buffer', 'Show the log of buffer over-runs and under-runs')
  150.     mui_logevents_but:=make_button('Events', 'Show the log of events')
  151.  
  152.     mui_prefsave_but:=make_button('Save', 'Save preferences')
  153.     mui_prefuse_but:=make_button('Use', 'Use preferences, changes are lost after reboot')
  154.     mui_prefcancel_but:=make_button('Cancel', 'Discard any changes')
  155.  
  156.  
  157.     mui_diagnostic_cyc:=make_keycycle(['Simple 1', 'Simple 2', 'Deep 1', 'Deep 2', NIL], "t", 'Choose diagnostic test')
  158.  
  159.     mui_device_tb:=BetterStringObject, StringFrame,
  160.                     MUIA_String_AdvanceOnCR, MUI_TRUE,
  161.                     MUIA_String_Contents, driver,
  162.                     MUIA_ShortHelp, 'Device driver to use',
  163.                     MUIA_CycleChain, 1,
  164.                     MUIA_ObjectID, OBID_DRIVER,
  165.                    End
  166.  
  167.     mui_unit_tb:=BetterStringObject, StringFrame,
  168.                     MUIA_String_AdvanceOnCR, MUI_TRUE,
  169.                     MUIA_String_Contents, unit,
  170.                     MUIA_ShortHelp, 'Device unit number',
  171.                     MUIA_String_Accept, '0123456789',
  172.                     MUIA_String_MaxLen, 4,
  173.                     MUIA_CycleChain, 1,
  174.                     MUIA_ObjectID, OBID_UNIT,
  175.                  End
  176.  
  177.     mui_status_tb:=TextObject, TextFrame,
  178.                     MUIA_String_Contents, 'Ready',
  179.                     MUIA_ShortHelp, 'SCSI/IDE target condition',
  180.                    End
  181.  
  182.     mui_probefrom_tb:=BetterStringObject, StringFrame,
  183.                     MUIA_String_AdvanceOnCR, MUI_TRUE,
  184.                     MUIA_String_Contents, probefrom,
  185.                     MUIA_ShortHelp, 'Probing devices starts at this unit',
  186.                     MUIA_String_Accept, '0123456789',
  187.                     MUIA_String_MaxLen, 4,
  188.                     MUIA_CycleChain, 1,
  189.                     MUIA_ObjectID, OBID_PROBEFROM,
  190.                  End
  191.  
  192.     mui_probeto_tb:=BetterStringObject, StringFrame,
  193.                     MUIA_String_AdvanceOnCR, MUI_TRUE,
  194.                     MUIA_String_Contents, probeto,
  195.                     MUIA_ShortHelp, 'Probing devices ends at this unit',
  196.                     MUIA_String_Accept, '0123456789',
  197.                     MUIA_String_MaxLen, 4,
  198.                     MUIA_CycleChain, 1,
  199.                     MUIA_ObjectID, OBID_PROBETO,
  200.                  End
  201.  
  202.  
  203.     app:=ApplicationObject,
  204.         MUIA_Application_Title      , 'Q-Device!',
  205.         MUIA_Application_Version    , '$VER: Q-Device! v0.3',
  206.         MUIA_Application_Copyright  , 'Written By Ian Chapman (2003)',
  207.         MUIA_Application_Author     , 'Ian Chapman',
  208.         MUIA_Application_Description, 'IDE/SCSI device query tool',
  209.         MUIA_Application_Base       , 'QDEVICE',
  210.         MUIA_Application_SingleTask , FALSE,
  211.         MUIA_Application_Menustrip  , Mui_MakeObjectA(MUIO_MenustripNM,[menu,0]),
  212.         MUIA_Application_HelpFile   , 'Q-Device!.guide',
  213.  
  214.         SubWindow, mui_main_win:=WindowObject,
  215.         MUIA_Window_Title       , 'Q-Device! V0.3 by Ian Chapman',
  216.         MUIA_Window_ID          , "QDEV",
  217.         MUIA_Window_Activate    , MUI_TRUE,
  218.  
  219.         WindowContents, VGroup,
  220.                         Child, HGroup,
  221.                             Child, Label('Driver:'),
  222.                             Child, PoplistObject,
  223.                                     MUIA_Popstring_String, mui_device_tb,
  224.                                     MUIA_Popstring_Button, PopButton( MUII_PopUp ),
  225.                                     MUIA_Poplist_Array, devicelist,
  226.                             End,
  227.                             Child, Label('Unit:'),                            
  228.                             Child, PoplistObject,
  229.                                     MUIA_Popstring_String, mui_unit_tb,
  230.                                     MUIA_Popstring_Button, PopButton( MUII_PopUp ),
  231.                                     MUIA_Poplist_Array, ['0', '1', '2', '3', '4', '5', '6', '7', '8', '9', '10', '11', '12', '13', '14', '15', NIL],
  232.                             End,
  233.                         End, ->HGroup
  234.                         Child, HGroup,
  235.                             Child, Label('Target Status:'),
  236.                             Child, mui_status_tb,
  237.                         End, -> HGroup
  238.                         Child, RegisterGroup(['Query', 'Control', 'Diagnostic', NIL]),
  239.                             Child, VGroup,
  240.                                 Child, ColGroup(3), GroupFrame,
  241.                                     Child, mui_probe_but,
  242.                                     Child, mui_inquire_but,
  243.                                     Child, mui_capacity_but,
  244.                                     Child, mui_testready_but,
  245.                                     Child, mui_modesense_but,
  246.                                     Child, mui_readtoc_but,
  247.                                 End, -> ColGroup
  248.                                 Child, VSpace(10),
  249.                                 Child, ColGroup(3), GroupFrameT('Firmware Logs'),
  250.                                     Child, mui_logsupport_but,
  251.                                     Child, mui_logwrite_but,
  252.                                     Child, mui_logread_but,
  253.                                     Child, mui_logrevread_but,
  254.                                     Child, mui_logverify_but,
  255.                                     Child, mui_lognmerrors_but,
  256.                                     ->Child, mui_logbuffer_but,
  257.                                     ->Child, mui_logevents_but,
  258.                                     ->Child, HSpace(0),
  259.                                 End, -> ColGroup
  260.                             End, -> VGroup
  261.                             Child, ColGroup(2),
  262.                                 Child, mui_powerup_but,
  263.                                 Child, mui_powerdown_but,
  264.                                 Child, mui_lock_but,
  265.                                 Child, mui_unlock_but,
  266.                                 Child, mui_insert_but,
  267.                                 Child, mui_eject_but,
  268.                             End, -> Colgroup
  269.                             Child, ColGroup(2), GroupFrameT('Diagnostic Tests'),
  270.                                 Child, HGroup,
  271.                                     Child, Label('_Test Type:'),
  272.                                     Child, mui_diagnostic_cyc,
  273.                                 End, -> HGroup
  274.                                 Child, mui_diagnostic_but,
  275.                             End, -> ColGroup
  276.                         End, -> Register,
  277.                         Child, BalanceObject, End,
  278.                         Child, mui_output_lv,
  279.                     End, ->VGroup
  280.                 End, -> WindowObject
  281.  
  282.         SubWindow, mui_prefs_win:=WindowObject,
  283.         MUIA_Window_Title       , 'Preferences',
  284.         MUIA_Window_ID          , "PREF",
  285.         MUIA_Window_Activate    , MUI_TRUE,
  286.         MUIA_HelpNode           , 'Preferences Window',
  287.  
  288.         WindowContents, VGroup,
  289.                             Child, ColGroup(2),
  290.                                 Child, Label('Probe Units From:'),
  291.                                 Child, HGroup,
  292.                                     Child, mui_probefrom_tb,
  293.                                     Child, Label('To:'),
  294.                                     Child, mui_probeto_tb,
  295.                                 End, -> HGroup
  296.                             End, -> ColGroup
  297.                             Child, BalanceObject, End,
  298.                             Child, HGroup,
  299.                                 Child, mui_prefsave_but,
  300.                                 Child, mui_prefuse_but,
  301.                                 Child, mui_prefcancel_but,
  302.                             End, -> HGroup
  303.                         End, -> VGroup
  304.         End, -> Window
  305.  
  306.  
  307.             End -> Application
  308.  
  309.     IF (app=NIL) THEN Raise(ERR_NOAPP)
  310.  
  311.     doMethodA(mui_inquire_but,      [MUIM_Notify, MUIA_Pressed, FALSE, app, 2, MUIM_Application_ReturnID, ID_INQUIRE])
  312.     doMethodA(mui_eject_but,        [MUIM_Notify, MUIA_Pressed, FALSE, app, 2, MUIM_Application_ReturnID, ID_EJECT])
  313.     doMethodA(mui_insert_but,       [MUIM_Notify, MUIA_Pressed, FALSE, app, 2, MUIM_Application_ReturnID, ID_INSERT])
  314.     doMethodA(mui_lock_but,         [MUIM_Notify, MUIA_Pressed, FALSE, app, 2, MUIM_Application_ReturnID, ID_LOCK])
  315.     doMethodA(mui_unlock_but,       [MUIM_Notify, MUIA_Pressed, FALSE, app, 2, MUIM_Application_ReturnID, ID_UNLOCK])
  316.     doMethodA(mui_capacity_but,     [MUIM_Notify, MUIA_Pressed, FALSE, app, 2, MUIM_Application_ReturnID, ID_CAPACITY])
  317.     doMethodA(mui_testready_but,    [MUIM_Notify, MUIA_Pressed, FALSE, app, 2, MUIM_Application_ReturnID, ID_TESTREADY])
  318.     doMethodA(mui_readtoc_but,      [MUIM_Notify, MUIA_Pressed, FALSE, app, 2, MUIM_Application_ReturnID, ID_READTOC])
  319.     doMethodA(mui_powerup_but,      [MUIM_Notify, MUIA_Pressed, FALSE, app, 2, MUIM_Application_ReturnID, ID_POWERUP])
  320.     doMethodA(mui_powerdown_but,    [MUIM_Notify, MUIA_Pressed, FALSE, app, 2, MUIM_Application_ReturnID, ID_POWERDOWN])
  321.     doMethodA(mui_probe_but,        [MUIM_Notify, MUIA_Pressed, FALSE, app, 2, MUIM_Application_ReturnID, ID_PROBE])
  322.     doMethodA(mui_diagnostic_but,   [MUIM_Notify, MUIA_Pressed, FALSE, app, 2, MUIM_Application_ReturnID, ID_DIAGNOSTIC])
  323.     doMethodA(mui_modesense_but,    [MUIM_Notify, MUIA_Pressed, FALSE, app, 2, MUIM_Application_ReturnID, ID_MODESENSE])
  324.     doMethodA(mui_logsupport_but,   [MUIM_Notify, MUIA_Pressed, FALSE, app, 2, MUIM_Application_ReturnID, ID_LOG_SUPPORT])
  325.     doMethodA(mui_logwrite_but,     [MUIM_Notify, MUIA_Pressed, FALSE, app, 2, MUIM_Application_ReturnID, ID_LOG_WRITE])
  326.     doMethodA(mui_logread_but,      [MUIM_Notify, MUIA_Pressed, FALSE, app, 2, MUIM_Application_ReturnID, ID_LOG_READ])
  327.     doMethodA(mui_logrevread_but,   [MUIM_Notify, MUIA_Pressed, FALSE, app, 2, MUIM_Application_ReturnID, ID_LOG_REVREAD])
  328.     doMethodA(mui_logverify_but,    [MUIM_Notify, MUIA_Pressed, FALSE, app, 2, MUIM_Application_ReturnID, ID_LOG_VERIFY])
  329.     doMethodA(mui_lognmerrors_but,  [MUIM_Notify, MUIA_Pressed, FALSE, app, 2, MUIM_Application_ReturnID, ID_LOG_NMERRORS])
  330.     doMethodA(mui_logbuffer_but,    [MUIM_Notify, MUIA_Pressed, FALSE, app, 2, MUIM_Application_ReturnID, ID_LOG_BUFFER])
  331.     doMethodA(mui_logevents_but,    [MUIM_Notify, MUIA_Pressed, FALSE, app, 2, MUIM_Application_ReturnID, ID_LOG_EVENTS])
  332.     doMethodA(mui_prefsave_but,     [MUIM_Notify, MUIA_Pressed, FALSE, app, 2, MUIM_Application_ReturnID, ID_SAVEPREF])
  333.     doMethodA(mui_prefuse_but,      [MUIM_Notify, MUIA_Pressed, FALSE, app, 2, MUIM_Application_ReturnID, ID_USEPREF])
  334.     doMethodA(mui_prefcancel_but,   [MUIM_Notify, MUIA_Pressed, FALSE, app, 2, MUIM_Application_ReturnID, ID_CANCELPREF])
  335.     doMethodA(mui_diagnostic_cyc,   [MUIM_Notify, MUIA_Cycle_Active, MUIV_EveryTime, mui_diagnostic_cyc, 3, MUIM_WriteLong, MUIV_TriggerValue, {diagflag}])
  336.     doMethodA(mui_device_tb,        [MUIM_Notify, MUIA_String_Contents, MUIV_EveryTime, mui_device_tb,    3, MUIM_WriteString, MUIV_TriggerValue, driver])
  337.     doMethodA(mui_unit_tb,          [MUIM_Notify, MUIA_String_Contents, MUIV_EveryTime, mui_unit_tb,      3, MUIM_WriteString, MUIV_TriggerValue, unit])
  338.     doMethodA(mui_probefrom_tb,     [MUIM_Notify, MUIA_String_Contents, MUIV_EveryTime, mui_probefrom_tb, 3, MUIM_WriteString, MUIV_TriggerValue, probefrom])
  339.     doMethodA(mui_probeto_tb,       [MUIM_Notify, MUIA_String_Contents, MUIV_EveryTime, mui_probeto_tb,   3, MUIM_WriteString, MUIV_TriggerValue, probeto])
  340.     doMethodA(mui_main_win,         [MUIM_Notify, MUIA_Window_CloseRequest, MUI_TRUE, app, 2, MUIM_Application_ReturnID, MUIV_Application_ReturnID_Quit])
  341.     doMethodA(mui_prefs_win,        [MUIM_Notify, MUIA_Window_CloseRequest, MUI_TRUE, app, 2, MUIM_Application_ReturnID, ID_CANCELPREF])
  342.     doMethodA(mui_output_lv,        [MUIM_Notify, MUIA_Listview_DoubleClick, MUI_TRUE, app, 2, MUIM_Application_ReturnID, ID_DOUBLECLICK])
  343.     set(mui_status_tb, MUIA_Text_Contents, 'Ready')
  344.     SetAttrsA(mui_main_win, [MUIA_Window_ActiveObject, mui_unit_tb, MUIA_Window_Open, MUI_TRUE, TAG_DONE])
  345.  
  346.     doMethodA(app, [MUIM_Application_Load, MUIV_Application_Load_ENV])
  347.  
  348.     IF (StrCmp(unit, '', ALL) = TRUE)
  349.         StrCopy(unit, '0')
  350.         set(mui_unit_tb, MUIA_String_Contents, '0')
  351.     ENDIF
  352.  
  353.     IF (StrCmp(driver, '', ALL) = TRUE)
  354.         StrCopy(driver, 'gvpscsi.device')
  355.         set(mui_device_tb, MUIA_String_Contents, 'gvpscsi.device')
  356.     ENDIF
  357.  
  358.     IF (StrCmp(probefrom, '', ALL) = TRUE)
  359.         StrCopy(probefrom, '0')
  360.         set(mui_probefrom_tb, MUIA_String_Contents, '0')
  361.     ENDIF
  362.  
  363.     IF (StrCmp(probeto, '', ALL) = TRUE)
  364.         StrCopy(probeto, '15')
  365.         set(mui_probeto_tb, MUIA_String_Contents, '15')
  366.     ENDIF
  367.  
  368.     WHILE running
  369.         result:=doMethodA(app, [MUIM_Application_Input,{signal}])
  370.         SELECT result
  371.             CASE MUIV_Application_ReturnID_Quit
  372.                 running:=FALSE
  373.             CASE ID_SAVEPREF
  374.                 doMethodA(app, [MUIM_Application_Save, MUIV_Application_Save_ENV])
  375.                 doMethodA(app, [MUIM_Application_Save, MUIV_Application_Save_ENVARC])
  376.                 set(mui_prefs_win, MUIA_Window_Open, FALSE)
  377.             CASE ID_USEPREF
  378.                 doMethodA(app, [MUIM_Application_Save, MUIV_Application_Save_ENV])
  379.                 set(mui_prefs_win, MUIA_Window_Open, FALSE)
  380.             CASE ID_CANCELPREF
  381.                 doMethodA(app, [MUIM_Application_Load, MUIV_Application_Load_ENV])
  382.                 set(mui_prefs_win, MUIA_Window_Open, FALSE)
  383.             CASE ID_PREFS
  384.                 set(mui_prefs_win, MUIA_Window_Open, MUI_TRUE)
  385.             CASE ID_INQUIRE
  386.                 doMethodA(mui_output_lst, [MUIM_List_Clear])
  387.                 inquiry_type:=TRUE
  388.                 query(driver, Val(unit), [SCSI_INQUIRY, 0, 0, 0, BUFFSIZE, 0]:cdb6, SIZEOF cdb6)
  389.             CASE ID_EJECT
  390.                 doMethodA(mui_output_lst, [MUIM_List_Clear])
  391.                 query(driver, Val(unit), [SCSI_CD_START_STOP_UNIT, 0, 0, 0, P_EJECT, 0]:cdb6, SIZEOF cdb6)
  392.             CASE ID_INSERT
  393.                 doMethodA(mui_output_lst, [MUIM_List_Clear])
  394.                 query(driver, Val(unit), [SCSI_CD_START_STOP_UNIT, 0, 0, 0, P_INSERT, 0]:cdb6, SIZEOF cdb6)
  395.             CASE ID_POWERUP
  396.                 doMethodA(mui_output_lst, [MUIM_List_Clear])
  397.                 query(driver, Val(unit), [SCSI_DA_START_STOP_UNIT, 0, 0, 0, P_START, 0]:cdb6, SIZEOF cdb6)
  398.             CASE ID_POWERDOWN
  399.                 doMethodA(mui_output_lst, [MUIM_List_Clear])
  400.                 query(driver, Val(unit), [SCSI_DA_START_STOP_UNIT, 0, 0, 0, P_STOP, 0]:cdb6, SIZEOF cdb6)
  401.             CASE ID_LOCK
  402.                 doMethodA(mui_output_lst, [MUIM_List_Clear])
  403.                 query(driver, Val(unit), [SCSI_CD_PREVENT_ALLOW_MEDIUM_REMOVAL, 0, 0, 0, P_LOCK, 0]:cdb6, SIZEOF cdb6)
  404.             CASE ID_UNLOCK
  405.                 doMethodA(mui_output_lst, [MUIM_List_Clear])
  406.                 query(driver, Val(unit), [SCSI_CD_PREVENT_ALLOW_MEDIUM_REMOVAL, 0, 0, 0, P_UNLOCK, 0]:cdb6, SIZEOF cdb6)
  407.             CASE ID_CAPACITY
  408.                 doMethodA(mui_output_lst, [MUIM_List_Clear])
  409.                 query(driver, Val(unit), [SCSI_DA_READ_CAPACITY, 0, 0, 0, 0, 0, 0, 0, 0, 0]:cdb10, SIZEOF cdb10)
  410.             CASE ID_TESTREADY
  411.                 doMethodA(mui_output_lst, [MUIM_List_Clear])
  412.                 query(driver, Val(unit), [SCSI_TEST_UNIT_READY, 0, 0, 0, 0, 0]:cdb6, SIZEOF cdb6)
  413.             CASE ID_READTOC
  414.                 doMethodA(mui_output_lst, [MUIM_List_Clear])
  415.                 query(driver, Val(unit), [SCSI_CD_READ_TOC, 0, 0, 0, 0, 0, 1, 0, BUFFSIZE, 0]:cdb10, SIZEOF cdb10)
  416.             CASE ID_PROBE
  417.                 doMethodA(mui_output_lst, [MUIM_List_Clear])
  418.                 inquiry_type:=MUI_TRUE
  419.                 IF Val(probefrom) > Val(probeto)
  420.                     FOR i:=Val(probefrom) TO Val(probeto) STEP -1 DO query(driver, i, [SCSI_INQUIRY, 0, 0, 0, BUFFSIZE, 0]:cdb6, SIZEOF cdb6)
  421.                 ELSE
  422.                     FOR i:=Val(probefrom) TO Val(probeto) DO query(driver, i, [SCSI_INQUIRY, 0, 0, 0, BUFFSIZE, 0]:cdb6, SIZEOF cdb6)
  423.                 ENDIF
  424.             CASE ID_DIAGNOSTIC
  425.                 doMethodA(mui_output_lst, [MUIM_List_Clear])
  426.                 SELECT diagflag
  427.                     CASE 0
  428.                         query(driver, Val(unit), [SCSI_SEND_DIAGNOSTIC, P_DIAG_SIMPLE1, 0, 0, 0, 0]:cdb6, SIZEOF cdb6)
  429.                     CASE 1
  430.                         query(driver, Val(unit), [SCSI_SEND_DIAGNOSTIC, P_DIAG_SIMPLE2, 0, 0, 0, 0]:cdb6, SIZEOF cdb6)
  431.                     CASE 2
  432.                         IF Mui_RequestA(app, mui_main_win, 0, 'Warning!', '_Proceed|*_Cancel', 'A deep test may require the device to take itself offline temporarily\nor make temporary changes to the medium. It is highly recommended\nyou make sure nothing else is accessing the device before performing\nthis test.', NIL)<>0
  433.                             query(driver, Val(unit), [SCSI_SEND_DIAGNOSTIC, P_DIAG_COMPLEX1, 0, 0, 0, 0]:cdb6, SIZEOF cdb6)
  434.                         ENDIF
  435.                     CASE 3
  436.                         IF Mui_RequestA(app, mui_main_win, 0, 'Warning!', '_Proceed|*_Cancel', 'A deep test may require the device to take itself offline temporarily\nor make temporary changes to the medium. It is highly recommended\nyou make sure nothing else is accessing the device before performing\nthis test.', NIL)<>0
  437.                             query(driver, Val(unit), [SCSI_SEND_DIAGNOSTIC, P_DIAG_COMPLEX2, 0, 0, 0, 0]:cdb6, SIZEOF cdb6)     
  438.                         ENDIF
  439.                 ENDSELECT
  440.             CASE ID_MODESENSE
  441.                 doMethodA(mui_output_lst, [MUIM_List_Clear])
  442.                 inquiry_type:=FALSE
  443.                 IF query(driver, Val(unit), [SCSI_INQUIRY, 0, 0, 0, BUFFSIZE, 0]:cdb6, SIZEOF cdb6)=0
  444.                     query(driver, Val(unit), [SCSI_MODE_SENSE_6, 0, P_ALLPAGES, 0, BUFFSIZE, 0]:cdb6, SIZEOF cdb6)
  445.                 ENDIF
  446.             CASE ID_LOG_SUPPORT
  447.                 doMethodA(mui_output_lst, [MUIM_List_Clear])
  448.                 query(driver, Val(unit), [SCSI_LOG_SENSE, 0, 0, 0, 0, 0, 0, BUFFSIZE, 0]:cdb10, SIZEOF cdb10)
  449.             CASE ID_LOG_WRITE
  450.                 doMethodA(mui_output_lst, [MUIM_List_Clear])
  451.                 query(driver, Val(unit), [SCSI_LOG_SENSE, 0, P_LOG_WRITE, 0, 0, 0, 0, BUFFSIZE, 0]:cdb10, SIZEOF cdb10)
  452.             CASE ID_LOG_READ
  453.                 doMethodA(mui_output_lst, [MUIM_List_Clear])
  454.                 query(driver, Val(unit), [SCSI_LOG_SENSE, 0, P_LOG_READ, 0, 0, 0, 0, BUFFSIZE, 0]:cdb10, SIZEOF cdb10)
  455.             CASE ID_LOG_REVREAD
  456.                 doMethodA(mui_output_lst, [MUIM_List_Clear])
  457.                 query(driver, Val(unit), [SCSI_LOG_SENSE, 0, P_LOG_REVREAD, 0, 0, 0, 0, BUFFSIZE, 0]:cdb10, SIZEOF cdb10)
  458.             CASE ID_LOG_VERIFY
  459.                 doMethodA(mui_output_lst, [MUIM_List_Clear])
  460.                 query(driver, Val(unit), [SCSI_LOG_SENSE, 0, P_LOG_VERIFY, 0, 0, 0, 0, BUFFSIZE, 0]:cdb10, SIZEOF cdb10)
  461.             CASE ID_LOG_NMERRORS
  462.                 doMethodA(mui_output_lst, [MUIM_List_Clear])
  463.                 query(driver, Val(unit), [SCSI_LOG_SENSE, 0, P_LOG_NMERRORS, 0, 0, 0, 0, BUFFSIZE, 0]:cdb10, SIZEOF cdb10)
  464.             CASE ID_LOG_BUFFER
  465.                 doMethodA(mui_output_lst, [MUIM_List_Clear])
  466.                 query(driver, Val(unit), [SCSI_LOG_SENSE, 0, P_LOG_BUFFER, 0, 0, 0, 0, BUFFSIZE, 0]:cdb10, SIZEOF cdb10)
  467.             CASE ID_LOG_EVENTS
  468.                 doMethodA(mui_output_lst, [MUIM_List_Clear])
  469.                 query(driver, Val(unit), [SCSI_LOG_SENSE, 0, P_LOG_EVENTS, 0, 0, 0, 0, BUFFSIZE, 0]:cdb10, SIZEOF cdb10)
  470.             CASE ID_ABOUT
  471.                 Mui_RequestA(app, mui_main_win, 0, 'About Q-Device!', '*_OK', '\ecQ-Device! by Ian Chapman (2003)\nVersion 0.3\n\nA low-level SCSI/IDE query, control and diagnostic tool\n\n\ebUse of this software is entirely at YOUR OWN risk!\en', NIL)
  472.             CASE ID_MUIABOUT
  473.                 doMethodA(app, [MUIM_Application_AboutMUI, mui_main_win])
  474.             CASE ID_MUISET
  475.                 doMethodA(app, [MUIM_Application_OpenConfigWindow, 0])
  476.             CASE ID_ICONIFY
  477.                 set(app, MUIA_Application_Iconified, MUI_TRUE)
  478.             CASE ID_DOUBLECLICK
  479.                 inquiry_type:=TRUE
  480.                 click_inquiry()
  481.         ENDSELECT
  482.         IF (running AND signal) THEN Wait(signal)
  483.     ENDWHILE
  484.  
  485.     EXCEPT DO
  486.         IF (app) THEN Mui_DisposeObject(app)
  487.         IF (muimasterbase) THEN CloseLibrary(muimasterbase)
  488.         SELECT exception
  489.             CASE NORMAL
  490.                 ->Normal Exit
  491.             CASE ERR_NOMUI
  492.                 PrintF('Unable to open muimaster.library V19+\n')
  493.             CASE ERR_NOAPP
  494.                 PrintF('Unable to create application\n')
  495.             DEFAULT
  496.                 PrintF('Unknown exception of type (\d)\n', exception)
  497.         ENDSELECT
  498. ENDPROC
  499.  
  500. /*
  501. ** This procedure takes a SCSI command definition, then passes the results to
  502. ** a handler procedure, depending on the SCSI command sent.
  503. */
  504. PROC query(device:PTR TO CHAR, unit, cmd:PTR TO cdb12, size) HANDLE
  505. DEF myport=NIL:PTR TO mp, ioreq=NIL:PTR TO iostd, buffer=NIL, scsiio:scsicmd,
  506.     command, error=-1, status
  507.  
  508.     IF (myport:=CreateMsgPort())=NIL THEN Raise(ERR_MP)
  509.     IF (ioreq:=createStdIO(myport))=NIL THEN Raise(ERR_IOR)
  510.     IF (error:=OpenDevice(device, unit, ioreq, 0)) <> NIL THEN Raise(ERR_DEVICE)
  511.  
  512.     buffer:=New(BUFFSIZE)
  513.     command:=cmd.opcode
  514.     scsiio.data:=buffer
  515.     scsiio.length:=BUFFSIZE
  516.     scsiio.command:=cmd
  517.     scsiio.cmdlength:=size
  518.     scsiio.flags:=SCSIF_READ -> OR SCSIF_AUTOSENSE
  519.     scsiio.senseactual:=0
  520.     ioreq.command:=HD_SCSICMD
  521.     ioreq.data:=scsiio
  522.     ioreq.length:=SIZEOF scsicmd
  523.     DoIO(ioreq)
  524.     status:=ioreq.error
  525.  
  526.     SELECT $FF OF (scsiio.status AND M_STATUS)
  527.         CASE 0
  528.             IF command <> SCSI_REQUEST_SENSE THEN set(mui_status_tb, MUIA_Text_Contents, 'Target Response: GOOD')
  529.             SELECT command
  530.                 CASE SCSI_CD_READ_TOC
  531.                     process_toc(buffer)
  532.                 CASE SCSI_TEST_UNIT_READY
  533.                     outlist_d('Unit Ready', device, unit)
  534.                 CASE SCSI_INQUIRY
  535.                     process_inquiry(device, unit, buffer)
  536.                 CASE SCSI_DA_READ_CAPACITY
  537.                     process_capacity(buffer)
  538.                 CASE SCSI_CD_START_STOP_UNIT
  539.                     IF cmd.param4=P_EJECT
  540.                         outlist_d('Sent eject command', device, unit)
  541.                     ELSEIF cmd.param4=P_INSERT
  542.                         outlist_d('Sent insert command', device, unit)
  543.                     ELSEIF cmd.param4=P_START
  544.                         outlist_d('Sent power up command', device, unit)
  545.                     ELSEIF cmd.param4=P_STOP
  546.                         outlist_d('Sent power down command', device, unit)
  547.                     ENDIF
  548.                 CASE SCSI_CD_PREVENT_ALLOW_MEDIUM_REMOVAL
  549.                     IF cmd.param4=P_LOCK
  550.                         outlist_d('Sent lock command', device, unit)
  551.                     ELSE
  552.                         outlist_d('Sent unlock command', device, unit)
  553.                     ENDIF
  554.                 CASE SCSI_REQUEST_SENSE
  555.                     process_sense(buffer)
  556.                 CASE SCSI_MODE_SENSE_6
  557.                     process_modesense(buffer)
  558.                 CASE SCSI_LOG_SENSE
  559.                     SELECT $3F OF Char(buffer)
  560.                         CASE $0
  561.                             outlist('\ebLog Type:\en', 'List of supported log types')
  562.                             process_log_support(buffer)
  563.                         CASE $1
  564.                             outlist('\ebLog Type:\en', 'Buffer over/under runs')
  565.                             process_log_buffer(buffer)
  566.                         CASE $2
  567.                             outlist('\ebLog Type:\en', 'Write Errors')
  568.                             process_log_errors(buffer)
  569.                         CASE $3
  570.                             outlist('\ebLog Type:\en', 'Read Errors')
  571.                             process_log_errors(buffer)
  572.                         CASE $4
  573.                             outlist('\ebLog Type:\en', 'Reverse Read Errors')
  574.                             process_log_errors(buffer)
  575.                         CASE $5
  576.                             outlist('\ebLog Type:\en', 'Verify Errors')
  577.                             process_log_errors(buffer)
  578.                         CASE $6
  579.                             outlist('\ebLog Type:\en', 'Errors not related to media')
  580.                             process_log_nmerrors(buffer)
  581.                         CASE $7
  582.                             outlist('\ebLog Type:\en', 'Last number of error events')
  583.                             process_log_events(buffer)
  584.                         DEFAULT
  585.                             outlist('\ebLog Type:\en', 'Vendor Specific Log')
  586.                     ENDSELECT
  587.                     
  588.                 CASE SCSI_SEND_DIAGNOSTIC
  589.                     outlist_d('Self Test Passed', device, unit)
  590.             ENDSELECT
  591.         CASE 2
  592.             IF command <> SCSI_REQUEST_SENSE  -> Hopefully avoids recursive loops with bad devices/drivers which don't support request sense.
  593.                 set(mui_status_tb, MUIA_Text_Contents, 'Target Response: CHECK_CONDITION')
  594.                 outlist('\ebWarning:\en', 'Command generated an error response (see below)')
  595.                 query(device, unit, [SCSI_REQUEST_SENSE, 0, 0, 0, BUFFSIZE, 0]:cdb6, SIZEOF cdb6)
  596.             ENDIF
  597.         CASE 4
  598.             set(mui_status_tb, MUIA_Text_Contents, 'Target Response: CONDITION_MET')
  599.         CASE 8
  600.             set(mui_status_tb, MUIA_Text_Contents, 'Target Response: BUSY')
  601.         CASE 16
  602.             set(mui_status_tb, MUIA_Text_Contents, 'Target Response: INTERMEDIATE')
  603.         CASE 20
  604.             set(mui_status_tb, MUIA_Text_Contents, 'Target Response: INTERMEDIATE_CONDITION_MET')
  605.         CASE 24
  606.             set(mui_status_tb, MUIA_Text_Contents, 'Target Response: RESERVATION_CONFLICT')
  607.         CASE 34
  608.             set(mui_status_tb, MUIA_Text_Contents, 'Target Response: COMMAND_TERMINATED')
  609.         CASE 72
  610.             set(mui_status_tb, MUIA_Text_Contents, 'Target Response: QUEUE_FULL')
  611.         DEFAULT
  612.             set(mui_status_tb, MUIA_Text_Contents, 'Target Response: UNKNOWN')
  613.     ENDSELECT
  614.  
  615.     SELECT status
  616.         CASE 0
  617.             ->Normal Return
  618.         CASE HFERR_SELFUNIT
  619.             outlist_d('<self issuing command error>', device, unit)
  620.         CASE HFERR_DMA
  621.             outlist_d('<DMA Failure>', device, unit)
  622.         CASE HFERR_PHASE
  623.             outlist_d('<illegal scsi phase>', device, unit)
  624.         CASE HFERR_PARITY
  625.             outlist_d('<parity error>', device, unit)
  626.         CASE HFERR_SELTIMEOUT
  627.             outlist_d('<device timed out>', device, unit)
  628.     ENDSELECT
  629.  
  630.     EXCEPT DO
  631.         IF error=NIL
  632.             IF  CheckIO(ioreq)<>NIL
  633.                 AbortIO(ioreq)
  634.                 WaitIO(ioreq)
  635.             ENDIF
  636.         ENDIF
  637.  
  638.         CloseDevice(ioreq)
  639.         IF ioreq <> NIL THEN deleteStdIO(ioreq)
  640.         IF myport <> NIL THEN DeleteMsgPort(myport)
  641.  
  642.         SELECT exception
  643.             CASE ERR_MP
  644.                 outlist('\ebError:\en', 'Unable to create message port')
  645.             CASE ERR_IOR
  646.                 outlist('\ebError:\en', 'Unable to create IORequest')
  647.             CASE ERR_DEVICE
  648.                 outlist_d('<no device>', device, unit)
  649.         ENDSELECT
  650.  
  651. ENDPROC exception
  652.  
  653. /*
  654. ** This procedure handles the data returned from an inquiry command. It has
  655. ** three modes of operation depending on the value of the 'inquiry_type' global
  656. ** variable. These are full (for full inquiry), minimum (for probes) and silent
  657. ** for passing the device type to the mode sense handler
  658. */
  659. PROC process_inquiry(device:PTR TO CHAR, unit, reply:PTR TO inquiry)
  660. DEF devtypestr[40]:STRING, buildstr[99]:STRING, vendor[8]:STRING,
  661.     product[16]:STRING, revision[4]:STRING, devtype=0
  662.  
  663.     devtype:=(reply.peripheral AND M_DEVTYPE)
  664.     global_devtype:=devtype
  665.  
  666.     SELECT devtype
  667.         CASE DEV_DIRECT
  668.             StrCopy(devtypestr, 'DIRECT ACCESS (eg Disk)')
  669.         CASE DEV_SEQUENTIAL
  670.             StrCopy(devtypestr, 'SEQUENTIAL ACCESS (eg Tape)')
  671.         CASE DEV_PRINTER
  672.             StrCopy(devtypestr, 'PRINTER')
  673.         CASE DEV_PROCESSOR
  674.             StrCopy(devtypestr, 'PROCESSOR')
  675.         CASE DEV_WRITEONCE
  676.             StrCopy(devtypestr, 'WRITE-ONCE (eg Optical Disc)')
  677.         CASE DEV_CDROM
  678.             StrCopy(devtypestr, 'CD-ROM')
  679.         CASE DEV_SCANNER
  680.             StrCopy(devtypestr, 'SCANNER')
  681.         CASE DEV_OPTICAL
  682.             StrCopy(devtypestr, 'OPTICAL MEMORY')
  683.         CASE DEV_CHANGER
  684.             StrCopy(devtypestr, 'MEDIUM CHANGER (eg Jukebox)')
  685.         CASE DEV_COMMS
  686.             StrCopy(devtypestr, 'COMMUNICATIONS')
  687.         DEFAULT
  688.             StrCopy(devtypestr, 'UNKNOWN')
  689.     ENDSELECT
  690.  
  691.     MidStr(vendor, reply, 8, 7)
  692.     MidStr(product, reply, 16, 16)
  693.     MidStr(revision, reply, 32, 4)
  694.  
  695.     IF inquiry_type=MUI_TRUE
  696.         StringF(buildstr, '\s \s \s :\s', vendor, product, revision, devtypestr)
  697.         outlist_d(buildstr, device, unit)
  698.     ELSEIF inquiry_type=TRUE
  699.         outlist('\ebDriver:\en', device)
  700.         outlist_i('\ebUnit:\en', unit, NIL)
  701.         outlist('\ebVendor:\en', vendor)
  702.         outlist('\ebProduct:\en', product)
  703.         outlist('\ebRevision:\en', revision)
  704.         outlist('\ebType:\en', devtypestr)
  705.         IF (reply.rmb AND M_RMB) = 128 THEN outlist('\ebRemovable Media:\en:', 'Yes') ELSE outlist('\ebRemovable Media:\en:', 'No')
  706.         outlist_i('\ebVendor Type Modifier:\en', (reply.rmb AND M_VENDORTYPE), NIL)
  707.         outlist_i('\ebISO Version:\en', (reply.versions AND M_ISOVER), NIL)
  708.         outlist_i('\ebECMA Version:\en', (reply.versions AND M_ECMAVER), NIL )
  709.         outlist_i('\ebANSI Version:\en', (reply.versions AND M_ANSIVER), ' (SCSI Version)')
  710.         IF (reply.aenc AND M_AENC) = 128 THEN outlist('\ebAENC Support:\en', 'Yes') ELSE outlist('\ebAENC Support:\en', 'No')
  711.         IF (reply.aenc AND M_TRMIOP) = 64 THEN outlist('\ebTrmIOP Support:\en', 'Yes') ELSE outlist('\ebTrmIOP Support:\en', 'No')
  712.         IF (reply.width AND M_RELADR) = 128 THEN outlist('\ebRelative Addressing:\en', 'Yes') ELSE outlist('\ebRelative Addressing:\en', 'No')
  713.         IF (reply.width AND M_WIDTH32) = 64 THEN outlist('\eb32bit Support:\en', 'Yes') ELSE outlist('\eb32bit Support:\en', 'No')
  714.         IF (reply.width  AND M_WIDTH16) = 32 THEN outlist('\eb16bit Support\en', 'Yes') ELSE outlist('\eb16bit Support\en', 'No')
  715.         outlist('\eb8bit Support\en', 'Yes')
  716.         IF (reply.width AND M_SYNC) = 16 THEN outlist('\ebSynchronous Support:\en', 'Yes') ELSE outlist('\ebSynchronous Support:\en', 'No')
  717.         IF (reply.width AND M_LINKED) = 8 THEN outlist('\ebLinked Support:\en', 'Yes') ELSE outlist('\ebLinked Support:\en', 'No')
  718.         IF (reply.width AND M_CMDQUE) = 2 THEN outlist('\ebCommand Queuing Support:\en', 'Yes') ELSE outlist('\ebCommand Queuing Support:\en', 'No')
  719.         IF (reply.width AND M_RESET) = 1 THEN outlist('\ebSupported Reset Type:\en', 'Soft') ELSE outlist('\ebSupported Reset Type:\en', 'Hard')        
  720.     ENDIF
  721. ENDPROC
  722.  
  723. /*
  724. ** This procedure handles the data returned from a capacity query
  725. */
  726. PROC process_capacity(reply:PTR TO capacity)
  727. DEF buildstr[99]:STRING, tcap, vcap
  728.  
  729.     tcap:=Div(Mul(Div(reply.blocks, 1024), reply.bsize), 1024)
  730.     vcap:=Div(Mul(Div(reply.blocks, 1000), reply.bsize), 1000)
  731.  
  732.     outlist_i('\ebBlocks:\en', reply.blocks, NIL)
  733.     outlist_i('\ebBlock Size:\en', reply.bsize, ' bytes')
  734.     IF tcap<1024 THEN StringF(buildstr, '~ \dMB', tcap) ELSE StringF(buildstr, '~ \d.\d GB  (\d MB)', Div(tcap, 1024), (Mod(tcap, 1024)/100), tcap)
  735.     outlist('\ebTrue Capacity:\en', buildstr)
  736.     IF vcap<1000 THEN StringF(buildstr, '~ \dmb', vcap) ELSE StringF(buildstr, '~ \d.\d gb  (\d mb)', Div(vcap, 1000), (Mod(vcap, 1000)/100), vcap)
  737.     outlist('\ebVendor Capacity:\en', buildstr)
  738.  
  739. ENDPROC
  740.  
  741. /*
  742. ** This procedure handles the data returned from a Read Table of Contents
  743. ** query
  744. */
  745. PROC process_toc(reply:PTR TO toc)
  746. DEF track:PTR TO toc_d, i
  747.  
  748.     outlist_i('\ebStarting Track:\eb', reply.firsttrack, NIL)
  749.     outlist_i('\ebLast Track:\eb', reply.lasttrack, NIL)
  750.  
  751.     track:=reply + SIZEOF toc
  752.  
  753.     FOR i:=reply.firsttrack TO reply.lasttrack
  754.         outlist(' ', ' ')
  755.         outlist_i('\ebTrack Number:\en', track.track, NIL)
  756.         IF (track.adr_ctrl AND M_TRACKTYPE)=0
  757.             outlist('\ebType:\en', 'AUDIO')
  758.             IF (track.adr_ctrl AND M_CHANNELS)=0 THEN outlist('\ebAudio Channels:\en', '2') ELSE outlist('\ebAudio Channels:\en', '4')
  759.             IF (track.adr_ctrl AND M_EMPHASIS)=0 THEN outlist('\ebEmphasis:\en', 'Audio IS pre-emphasised') ELSE outlist('\ebEmphasis:\en', 'Audio NOT pre-emphasised')
  760.         ELSE
  761.             outlist('\ebTrack Type:\en', 'DATA')
  762.         ENDIF
  763.         IF (track.adr_ctrl AND M_COPYRIGHT)=0 THEN outlist('\ebCopyright:\en', 'Digital Copy Prohibited') ELSE outlist('\ebCopyright:\en', 'Digital Copy Permitted')
  764.         track:=track + SIZEOF toc_d
  765.     ENDFOR
  766.  
  767. ENDPROC
  768.  
  769. /*
  770. ** This procedure handles the data returned from a request sense key query
  771. */
  772. PROC process_sense(reply:PTR TO r_sense)
  773. DEF key ->cmdinfo:PTR TO r_sense_d, key
  774.  
  775.     key:=(reply.sensekey AND M_SENSEKEY)
  776.     ->cmdinfo:=reply + SIZEOF r_sense
  777.  
  778.     SELECT key
  779.         CASE $0
  780.             outlist_h('\ebSense Key:\en', key, ' : No Specific Sense Key Info Available')
  781.         CASE $1
  782.             outlist_h('\ebSense Key:\en', key, ' : Command recovered successfully from error')
  783.         CASE $2
  784.             outlist_h('\ebSense Key:\en', key, ' : Unit is not ready for commands')
  785.         CASE $3
  786.             outlist_h('\ebSense Key:\en', key, ' : Medium Error. The medium may contain errors or defects.')
  787.         CASE $4
  788.             outlist_h('\ebSense Key:\en', key, ' : DEVICE REPORTED HARDWARE FAILURE!!!')
  789.         CASE $5
  790.             outlist_h('\ebSense Key:\en', key, ' : This device does not support that command')
  791.         CASE $6
  792.             outlist_h('\ebSense Key:\en', key, ' : Unit Attention, possible media change in progress')
  793.         CASE $7
  794.             outlist_h('\ebSense Key:\en', key, ' : Medium is write-protected')
  795.         CASE $8
  796.             outlist_h('\ebSense Key:\en', key, ' : Attempt to read unformatted medium')
  797.         CASE $9
  798.             outlist_h('\ebSense Key:\en', key, ' : Vendor specific sense key')
  799.         CASE $A
  800.             outlist_h('\ebSense Key:\en', key, ' : Copy/Compare command aborted due to read/write error')
  801.         CASE $B
  802.             outlist_h('\ebSense Key:\en', key, ' : Command was aborted by the device')
  803.         CASE $C
  804.             outlist_h('\ebSense Key:\en', key, ' : Equal comparison satisfied')
  805.         CASE $D
  806.             outlist_h('\ebSense Key:\en', key, ' : Volume Overflow')
  807.         CASE $E
  808.             outlist_h('\ebSense Key:\en', key, ' : Miscompare')
  809.         DEFAULT
  810.             outlist_h('\ebSense Key:\en', key, ' : Reserved Sense Key')
  811.     ENDSELECT
  812.  
  813.     IF reply.sensecode > NIL
  814.         outlist_h('\ebSense Code:\en', reply.sensecode, NIL)
  815.         outlist_h('\ebSense Code Qualifier:\en', reply.sensequal, NIL)
  816.     ENDIF
  817.  
  818. ENDPROC
  819.  
  820. /*
  821. ** This procedure handles the data returned from a mode sense request
  822. ** (ie Device Parameters). It is quite complex because the data is in the form
  823. ** of many pages which have to be processed. In addition to that, a page type
  824. ** may have to be processed differently, or have a different meaning depending
  825. ** on the type of device queried.
  826. */
  827. PROC process_modesense(reply:PTR TO m_sense)
  828. DEF page:PTR TO CHAR, pagetype
  829.  
  830.     ->outlist_i('\ebMode Data Length:\en', reply.datalen, ' bytes')
  831.     IF reply.medium = 0 THEN outlist('\ebInserted Medium Type:\en', 'Default') ELSE outlist_i('\ebInserted Medium Type:\en', reply.medium, ' (See supported media page)')
  832.     ->outlist_i('\ebDescriptor Length:\en', reply.desclen, ' bytes')
  833.  
  834.     IF reply.desclen = 8
  835.         outlist_i('\ebLogical Blocks:\en', (reply.blocks AND M_LBLOCKS), NIL)
  836.         outlist_i('\ebLogical Block Length:\en', (reply.blocklen AND M_LBLOCKS), ' bytes')
  837.         page:=(reply + SIZEOF m_sense)
  838.  
  839.         WHILE page < (reply + reply.datalen)
  840.             pagetype:=(Char(page) AND M_PAGETYPE)
  841.             outlist(' ', ' ')
  842.  
  843.             SELECT pagetype
  844.                 CASE $1
  845.                     SELECT $A OF global_devtype
  846.                         CASE DEV_DIRECT
  847.                             outlist('\ebInformation Page:\en', 'Error Recovery Parameters')
  848.                             ->outlist_i('\ebPage Length:\en', Char(page+1), ' bytes')
  849.                             outlist_i('\ebRetries on Read Error:\en', Char(page+3), NIL)
  850.                             outlist_i('\ebRetries on Write Error:\en', Char(page+8), NIL)
  851.                             outlist_i('\ebCorrection Span:\en', Char(page+4), NIL)
  852.                             outlist_i('\ebHead Offset Count:\en', Char(page+5), NIL)
  853.                             outlist_i('\ebData Strobe Offset Count:\en', Char(page+6), NIL)
  854.                         CASE DEV_SEQUENTIAL
  855.                             outlist('\ebInformation Page:\en', 'Error Recovery Parameters')
  856.                             ->outlist_i('\ebPage Length:\en', Char(page+1), NIL)
  857.                             outlist_i('\ebRetries on Read Error:\en', Char(page+3), NIL)
  858.                             outlist_i('\ebRetries on Write Error:\en', Char(page+8), NIL)
  859.                         CASE DEV_CDROM
  860.                             outlist('\ebInformation Page:\en', 'Error Recovery Parameters')
  861.                             ->outlist_i('\ebPage Length:\en', Char(page+1), NIL)
  862.                             outlist_i('\ebRetries on Read Error:\en', Char(page+3), NIL)
  863.                     ENDSELECT
  864.                 CASE $2
  865.                     outlist('\ebInformation Page:\en', 'Disconnection and Reconnection Parameters')
  866.                     ->outlist_i('\ebPage Length:\en', Char(page+1), ' bytes')
  867.                     outlist_i('\ebBuffer Full Ratio:\en', Char(page+2), NIL)
  868.                     outlist_i('\ebBuffer Empty Ratio:\en', Char(page+3), NIL)
  869.                     outlist_i('\ebBus Inactivity Limit:\en', Int(page+4), NIL)
  870.                     outlist_i('\ebDisconnect Time Limit:\en', Int(page+6), NIL)
  871.                     outlist_i('\ebConnect Time Limit:\en', Int(page+8), NIL)
  872.                     outlist_i('\ebMaximum Burst Size:\en', Int(page+10), NIL)
  873.                 CASE $3
  874.                     IF global_devtype=DEV_DIRECT
  875.                         outlist('\ebInformation Page:\en', 'Formatting Parameters')
  876.                         ->outlist_i('\ebPage Length:\en', Char(page+1), ' bytes')
  877.                         outlist_i('\ebTracks Per Zone:\en', Int(page+2), NIL)
  878.                         outlist_i('\ebAlt. Sectors Per Zone:\en', Int(page+4), NIL)
  879.                         outlist_i('\ebAlt. Tracks Per Zone:\en', Int(page+6), NIL)
  880.                         outlist_i('\ebAlt. Tracks Per Logical Unit:\en', Int(page+8), NIL)
  881.                         outlist_i('\ebSectors Per Track:\en', Int(page+10), NIL)
  882.                         outlist_i('\ebBytes Per Physical Sector:\en', Int(page+12), NIL)
  883.                         outlist_i('\ebInterleave:\en', Int(page+14), NIL)
  884.                         outlist_i('\ebTrack Skew Factor:\en', Int(page+16), NIL)
  885.                         outlist_i('\ebCylinder Skew Factor:\en', Int(page+18), NIL)
  886.                     ENDIF
  887.                 CASE $4
  888.                     IF global_devtype=DEV_DIRECT
  889.                         outlist('\ebInformation Page:\en', 'Rigid Disk Geometry Parameters')
  890.                         ->outlist_i('\ebPage Length:\en', Char(page+1), ' bytes')
  891.                         outlist_i('\ebCylinders:\en', Int(page+2), NIL)
  892.                         outlist_i('\ebHeads:\en', Char(page+5), NIL)
  893.                         IF Int(page+12) = 0 THEN outlist('\ebStep Rate\en:', 'Device Default') ELSE outlist_i('\ebStep Rate:\en', Int(page+12)*100, ' ns')
  894.                         outlist_i('\ebLanding Cylinder:\en', Int(page+14), NIL)
  895.                         outlist_i('\ebRotation Rate:', Int(page+20), ' rpm')
  896.                     ENDIF
  897.                 CASE $5
  898.                     IF global_devtype=DEV_DIRECT
  899.                         outlist('\ebInformation Page:\en', 'Flexible Disk Geometry Parameters')
  900.                         ->outlist_i('\ebPage Length:\en', Char(page+1), ' bytes')
  901.                         outlist_i('\ebTransfer Rate\en', (Int(page+2)/8), ' K/sec')
  902.                         outlist_i('\ebHeads\en:', Char(page+4), NIL)
  903.                         outlist_i('\ebSecters Per Track:\en', Char(page+5), NIL)
  904.                         outlist_i('\ebBytes Per Sector:\en', Int(page+6), NIL)
  905.                         outlist_i('\ebCylinders:\en', Int(page+8), NIL)
  906.                         IF Int(page+14) = 0 THEN outlist('\ebStep Rate\en:', 'Device Default') ELSE outlist_i('\ebStep Rate:\en', Int(page+14)*100, ' us')
  907.                         outlist_i('\ebRotation Rate:\en', Int(page+28), ' rpm') 
  908.                     ENDIF
  909.                 CASE $7
  910.                     SELECT $A OF global_devtype
  911.                         CASE DEV_DIRECT
  912.                             outlist('\ebInformation Page:\en', 'Verify Error Recovery Parameters')
  913.                             ->outlist_i('\ebPage Length:\en', Char(page+1), ' bytes')
  914.                             outlist_i('\ebVerify Retries:\en', Char(page+3), NIL)
  915.                             outlist_i('\ebVerify Correction Span:\en', Char(page+4), NIL)
  916.                         CASE DEV_CDROM
  917.                             outlist('\ebInformation Page:\en', 'Verify Error Recovery Parameters')
  918.                             ->outlist_i('\ebPage Length:\en', Char(page+1), ' bytes')
  919.                             outlist_h('\ebError Recovery Parameter:\en', Char(page+2), NIL)
  920.                             outlist_i('\ebVerify Retries:\en', Char(page+3), NIL)
  921.                     ENDSELECT
  922.                 CASE $8
  923.                     SELECT $A OF global_devtype
  924.                         CASE DEV_DIRECT, DEV_CDROM, DEV_OPTICAL
  925.                         outlist('\ebInformation Page:\en', 'Cache Parameters')
  926.                         ->outlist_i('\ebPage Length:\en', Char(page+1), ' bytes')
  927.                         IF (Char(page+2) AND M_READCACHE) = 0 THEN outlist('\ebRead Cache:\en', 'Enabled') ELSE outlist('\ebRead Cache:\en', 'Disabled or Unavailable')
  928.                         outlist_i('\ebMin Pre-Fetch:\en', Int(page+6), ' bytes')
  929.                         outlist_i('\ebMax Pre-Fetch:\en', Int(page+8), ' bytes')
  930.                     ENDSELECT
  931.                 CASE $9
  932.                     outlist('\ebInformation Page:\en', 'Interface Mode')
  933.                     ->outlist_i('\ebPage Length:\en', Char(page+1), ' bytes')
  934.                     IF (Int(page+2)) = 0
  935.                         outlist('\ebInterface ID:\en', 'Small Computer Systems Interface (SCSI)')
  936.                     ELSEIF (Int(page+2))=1
  937.                         outlist('\ebInterface ID:\en', 'Storage Module Interface (SMI)')
  938.                     ELSEIF (Int(page+2))=2
  939.                         outlist('\ebInterface ID:\en', 'Enhanced Small Device Interface (ESDI)')
  940.                     ELSEIF (Int(page+2))=3
  941.                         outlist('\ebInterface ID:\en', 'Intelligent Peripheral Interface 2 (IPI-2)')
  942.                     ELSEIF (Int(page+2))=4
  943.                         outlist('\ebInterface ID:\en', 'Intelligent Peripheral Interface 3 (IPI-3)')
  944.                     ELSE
  945.                         outlist('\ebInterface ID:\en', 'Vendor Specific')
  946.                     ENDIF
  947.                 CASE $A
  948.                     outlist('\ebInformation Page:\en', 'Control Mode')
  949.                     ->outlist_i('\ebPage Length:\en', Char(page+1), ' bytes')
  950.                     IF (Char(page+3) AND M_QALGORITHM)=16
  951.                         outlist('\ebQueuing Algorithm:\en', 'Unrestricted reordering allowed')
  952.                     ELSEIF (Char(page+3) AND M_QALGORITHM)=0
  953.                         outlist('\ebQueuing Algorithm:\en', 'Restricted reordering')
  954.                     ELSE
  955.                         outlist('\ebQueuing Algorithm:\en', 'Vendor Specific')
  956.                     ENDIF
  957.                     IF (Char(page+3) AND M_QUEUING)=1
  958.                         outlist('\ebQueuing:', 'Disabled')
  959.                     ELSE
  960.                         outlist('\ebQueuing:', 'Enabled')
  961.                     ENDIF
  962.                 CASE $B
  963.                     SELECT $A OF global_devtype
  964.                         CASE DEV_DIRECT
  965.                             outlist('\ebInformation Page:\en', 'Supported Media')
  966.                             ->outlist_i('\ebPage Length:\en', Char(page+1), ' bytes')
  967.                             outlist_i('\ebMedium Type 1:\en', Char(page+4), NIL)
  968.                             outlist_i('\ebMedium Type 2:\en', Char(page+5), NIL)
  969.                             outlist_i('\ebMedium Type 3:\en', Char(page+6), NIL)
  970.                             outlist_i('\ebMedium Type 4:\en', Char(page+7), NIL)
  971.                         CASE DEV_CDROM
  972.                             outlist('\ebInformation Page:\en', 'Supported Media')
  973.                             ->outlist_i('\ebPage Length:\en', Char(page+1), ' bytes')
  974.                             IF Char(page+4) = NIL
  975.                                 outlist('\ebMedium Type 1:\en', 'Only the Default medium')
  976.                             ELSEIF Char(page+4) = 1
  977.                                 outlist('\ebMedium Type 1:\en', '120mm Data CD-ROM')
  978.                             ELSEIF Char(page+4) = 2
  979.                                 outlist('\ebMedium Type 1:\en', '120mm Audio CD-ROM')
  980.                             ELSEIF Char(page+4) = 3
  981.                                 outlist('\ebMedium Type 1:\en', '120mm Mixed Data & Audio')
  982.                             ELSEIF Char(page+4) = 5
  983.                                 outlist('\ebMedium Type 1:\en', '80mm Data CD-ROM')
  984.                             ELSEIF Char(page+4) = 6
  985.                                 outlist('\ebMedium Type 1:\en', '80mm Audio CD-ROM')
  986.                             ELSEIF Char(page+4) = 7
  987.                                 outlist('\ebMedium Type 1:\en', '80mm Mixed Data & Audio')
  988.                             ELSE
  989.                                 outlist('\ebMedium Type 1:\en', 'Vendor Specific')
  990.                             ENDIF
  991.                    
  992.                             IF Char(page+5) = NIL
  993.                                 outlist('\ebMedium Type 2:\en', 'Only the Default medium')
  994.                             ELSEIF Char(page+5) = 1
  995.                                 outlist('\ebMedium Type 2:\en', '120mm Data CD-ROM')
  996.                             ELSEIF Char(page+5) = 2
  997.                                 outlist('\ebMedium Type 2:\en', '120mm Audio CD-ROM')
  998.                             ELSEIF Char(page+5) = 3
  999.                                 outlist('\ebMedium Type 2:\en', '120mm Mixed Data & Audio')
  1000.                             ELSEIF Char(page+5) = 5
  1001.                                 outlist('\ebMedium Type 2:\en', '80mm Data CD-ROM')
  1002.                             ELSEIF Char(page+5) = 6
  1003.                                 outlist('\ebMedium Type 2:\en', '80mm Audio CD-ROM')
  1004.                             ELSEIF Char(page+5) = 7
  1005.                                 outlist('\ebMedium Type 2:\en', '80mm Mixed Data & Audio')
  1006.                             ELSE
  1007.                                 outlist('\ebMedium Type 2:\en', 'Vendor Specific')
  1008.                             ENDIF
  1009.  
  1010.                             IF Char(page+6) = NIL
  1011.                                 outlist('\ebMedium Type 3:\en', 'Only the Default medium')
  1012.                             ELSEIF Char(page+6) = 1
  1013.                                 outlist('\ebMedium Type 3:\en', '120mm Data CD-ROM')
  1014.                             ELSEIF Char(page+6) = 2
  1015.                                 outlist('\ebMedium Type 3:\en', '120mm Audio CD-ROM')
  1016.                             ELSEIF Char(page+6) = 3
  1017.                                 outlist('\ebMedium Type 3:\en', '120mm Mixed Data & Audio')
  1018.                             ELSEIF Char(page+6) = 5
  1019.                                 outlist('\ebMedium Type 3:\en', '80mm Data CD-ROM')
  1020.                             ELSEIF Char(page+6) = 6
  1021.                                 outlist('\ebMedium Type 3:\en', '80mm Audio CD-ROM')
  1022.                             ELSEIF Char(page+6) = 7
  1023.                                 outlist('\ebMedium Type 3:\en', '80mm Mixed Data & Audio')
  1024.                             ELSE
  1025.                                 outlist('\ebMedium Type 3:\en', 'Vendor Specific')
  1026.                             ENDIF
  1027.  
  1028.                             IF Char(page+7) = NIL
  1029.                                 outlist('\ebMedium Type 4:\en', 'Only the Default medium')
  1030.                             ELSEIF Char(page+7) = 1
  1031.                                 outlist('\ebMedium Type 4:\en', '120mm Data CD-ROM')
  1032.                             ELSEIF Char(page+7) = 2
  1033.                                 outlist('\ebMedium Type 4:\en', '120mm Audio CD-ROM')
  1034.                             ELSEIF Char(page+7) = 3
  1035.                                 outlist('\ebMedium Type 4:\en', '120mm Mixed Data & Audio')
  1036.                             ELSEIF Char(page+7) = 5
  1037.                                 outlist('\ebMedium Type 4:\en', '80mm Data CD-ROM')
  1038.                             ELSEIF Char(page+7) = 6
  1039.                                 outlist('\ebMedium Type 4:\en', '80mm Audio CD-ROM')
  1040.                             ELSEIF Char(page+7) = 7
  1041.                                 outlist('\ebMedium Type 4:\en', '80mm Mixed Data & Audio')
  1042.                             ELSE
  1043.                                 outlist('\ebMedium Type 4:\en', 'Vendor Specific')
  1044.                             ENDIF
  1045.                     ENDSELECT
  1046.                 CASE $C
  1047.                     IF global_devtype=DEV_DIRECT
  1048.                         outlist('\ebInformation Page:\en', 'Notch Parameters')
  1049.                         ->outlist_i('\ebPage Length:\en', Char(page+1), ' bytes')
  1050.                         outlist_i('\ebMax Notches:\en', Int(page+4), NIL)
  1051.                         outlist_i('\ebActive Notch:\en', Int(page+6), NIL)
  1052.                     ENDIF
  1053.                 CASE $D
  1054.                     IF global_devtype=DEV_CDROM
  1055.                         outlist('\ebInformation Page:\en', 'CD-ROM Parameters')
  1056.                         ->outlist_i('\ebPage Length:\en', Char(page+1), ' bytes')
  1057.                         outlist_h('\ebInactivity Multiplier:\en', (Char(page+3) AND M_INAC_MPLIER), NIL)
  1058.                         outlist_i('\ebS Units per MSF:\en', Int(page+4), NIL)
  1059.                         outlist_i('\ebF Units per MSF:\en', Int(page+6), NIL)
  1060.                     ENDIF
  1061.                 CASE $E
  1062.                     IF global_devtype=DEV_CDROM
  1063.                         outlist('\ebInformation Page:\en', 'CD-ROM Audio Parameters')
  1064.                         ->outlist_i('\ebPage Length:\en', Char(page+1), ' bytes')
  1065.                         outlist_i('\ebPort 0 Volume Level:\en', Char(page+9), NIL)
  1066.                         outlist_i('\ebPort 1 Volume Level:\en', Char(page+11), NIL)
  1067.                         outlist_i('\ebPort 2 Volume Level:\en', Char(page+13), NIL)
  1068.                         outlist_i('\ebPort 3 Volume Level:\en', Char(page+15), NIL)
  1069.                     ENDIF
  1070.                 CASE $10
  1071.                     IF global_devtype=DEV_SEQUENTIAL
  1072.                         outlist('\ebInformation Page:\en', 'Sequential Device Configuration')
  1073.                         ->outlist_i('\ebPage Length:\en', Char(page+1), ' bytes')
  1074.                         outlist_i('\ebActive Recording Format:\en', (Char(page+2) AND M_RECFORMAT), ' (All values are vendor specific)')
  1075.                         outlist_i('\ebActive Logical Partition:\en', Char(page+3), NIL)
  1076.                         outlist_i('\ebWrite Buffer Ratio:\en', Char(page+4), NIL)
  1077.                         outlist_i('\ebRead Buffer Ratio:\en', Char(page+5), NIL)
  1078.                         outlist_i('\ebWrite Delay:\en', Int(page+6)*100, ' ms')
  1079.                         IF Char(page+9) = 0 THEN outlist('\ebGap Size:\en', 'Device Default') ELSE outlist_i('\ebGap Size:\en', Char(page+9), NIL)
  1080.                         IF Char(page+14) = 0
  1081.                             outlist('\ebCompression:\en', 'Unavailable or disabled')
  1082.                         ELSEIF  Char(page+14) = 1
  1083.                             outlist('\ebCompression:\en', 'Enabled')
  1084.                         ENDIF
  1085.                     ENDIF
  1086.             ENDSELECT
  1087.             ->outlist_i('\ebInformation Page:\en', pagetype , NIL)
  1088.         page:=(page + Char(page+1) +2)
  1089.  
  1090.         ENDWHILE
  1091.  
  1092.     ENDIF
  1093.     
  1094. ENDPROC
  1095.  
  1096.  
  1097. PROC process_log_support(reply:PTR TO l_sense)
  1098. DEF x=0
  1099.  
  1100.     ->outlist_i('\ebLog Size:\en', reply.len, ' bytes')
  1101.     outlist(' ', ' ')
  1102.  
  1103.     FOR x:=0 TO (reply.len-1)
  1104.         SELECT $3F OF Char(reply+x+4)
  1105.             CASE $0
  1106.                 ->No real point in listing it, we know the disk supports it or we wouldn't get a reply
  1107.                 ->outlist_h('\ebFound Log:\en', Char(reply+x+4), ':  List of supported log types')
  1108.             CASE $1
  1109.                 outlist_h('\ebFound Log:\en', Char(reply+x+4), ':  Buffer Over-run and Under-run Log')
  1110.             CASE $2
  1111.                 outlist_h('\ebFound Log:\en', Char(reply+x+4), ':  Write Error Log')
  1112.             CASE $3
  1113.                 outlist_h('\ebFound Log:\en', Char(reply+x+4), ':  Read Error Log')
  1114.             CASE $4
  1115.                 outlist_h('\ebFound Log:\en', Char(reply+x+4), ':  Reverse-Read Error Log')
  1116.             CASE $5
  1117.                 outlist_h('\ebFound Log:\en', Char(reply+x+4), ':  Verify Error Log')
  1118.             CASE $6
  1119.                 outlist_h('\ebFound Log:\en', Char(reply+x+4), ':  Non-medium Error Log')
  1120.             CASE $7
  1121.                 outlist_h('\ebFound Log:\en', Char(reply+x+4), ':  Last # of Error Event Log')
  1122.             DEFAULT
  1123.                 outlist_h('\ebFound Log:\en', Char(reply+x+4), ':  A Vendor Specific Log')
  1124.         ENDSELECT
  1125.     ENDFOR
  1126.  
  1127. ENDPROC
  1128.  
  1129.  
  1130. PROC process_log_errors(reply:PTR TO l_sense)
  1131. DEF param:PTR TO l_param, plen=0, buildstr[100]:STRING
  1132.  
  1133.     ->outlist_i('\ebLog Size:\en', reply.len, ' bytes')
  1134.     param:=reply + (SIZEOF l_sense)
  1135.     outlist(' ', ' ')
  1136.  
  1137.     WHILE param < (reply + reply.len)
  1138.         SELECT $FF OF param.pcode2
  1139.             CASE $0
  1140.                 StrCopy(buildstr, '\ebErrors Corrected w/o Delay:\en')
  1141.             CASE $1
  1142.                 StrCopy(buildstr, '\ebErrors Corrected w/ Delay:\en')
  1143.             CASE $2
  1144.                 StrCopy(buildstr, '\ebTotal Re-writes or Re-reads:\en')
  1145.             CASE $3
  1146.                 StrCopy(buildstr, '\ebTotal Errors Corrected:\en')
  1147.             CASE $4
  1148.                 StrCopy(buildstr, '\ebTimes Correction Algorithm Used:\en')
  1149.             CASE $5
  1150.                 StrCopy(buildstr, '\ebTotal Bytes Processed:\en')
  1151.             CASE $6
  1152.                 StrCopy(buildstr, '\ebUncorrected Errors:\en')
  1153.             DEFAULT
  1154.                 StrCopy(buildstr, '\ebVendor Parameter\en:')
  1155.         ENDSELECT
  1156.  
  1157.         -> This section is largely for programming diagnostics, not too useful
  1158.         -> for the end user
  1159.         /*
  1160.         outlist_i('\ebPCB:\en', param.pcb, NIL)
  1161.         outlist_i('\ebDU:\en', param.pcb AND %10000000, NIL)
  1162.         outlist_i('\ebDS:\en', param.pcb AND %01000000, NIL)
  1163.         outlist_i('\ebTSD:\en', param.pcb AND %00100000, NIL)
  1164.         outlist_i('\ebETC:\en', param.pcb AND %00010000, NIL)
  1165.         outlist_i('\ebTMC:\en', param.pcb AND %00001100, NIL)
  1166.         outlist_i('\ebReserved:\en', param.pcb AND %00000010, NIL)
  1167.         outlist_i('\ebLP:\en', param.pcb AND %00000001, NIL)
  1168.         outlist_i('\ebParameter Length:\en', param.len, NIL)
  1169.         */
  1170.  
  1171.         plen:=param.len
  1172.         param:=param + (SIZEOF l_param) 
  1173.  
  1174.         IF plen = 1
  1175.             outlist_i(buildstr, Char(param), NIL)
  1176.         ELSEIF plen = 2
  1177.             outlist_i(buildstr, Int(param), NIL)
  1178.         ELSEIF plen = 4
  1179.             outlist_i(buildstr, Long(param), NIL)
  1180.         ELSEIF plen = 8
  1181.             outlist_i(buildstr, Long(param), ' (First longword)')
  1182.             outlist_i(' ', Long(param+4), ' (Second longword)')
  1183.         ELSE
  1184.             outlist(buildstr, 'Cannot Decode')
  1185.         ENDIF
  1186.  
  1187.         param:=param + plen
  1188.  
  1189.     ENDWHILE
  1190.  
  1191. ENDPROC
  1192.  
  1193. PROC process_log_nmerrors(reply:PTR TO l_sense)
  1194. DEF param:PTR TO l_param, plen=0, buildstr[100]:STRING
  1195.  
  1196.     ->outlist_i('\ebLog Size:\en', reply.len, ' bytes')
  1197.     param:=reply + (SIZEOF l_sense)
  1198.     outlist(' ', ' ')
  1199.  
  1200.     WHILE param < (reply + reply.len)
  1201.         
  1202.  
  1203.         SELECT $FF OF param.pcode2
  1204.             CASE $0
  1205.                 StrCopy(buildstr, '\ebNon-Medium Error Count:\en')
  1206.             DEFAULT
  1207.                 StrCopy(buildstr, '\ebVendor Parameter:\en')
  1208.         ENDSELECT
  1209.  
  1210.         /*
  1211.         outlist_i('\ebPCB:\en', param.pcb, NIL)
  1212.         outlist_i('\ebDU:\en', param.pcb AND %10000000, NIL)
  1213.         outlist_i('\ebDS:\en', param.pcb AND %01000000, NIL)
  1214.         outlist_i('\ebTSD:\en', param.pcb AND %00100000, NIL)
  1215.         outlist_i('\ebETC:\en', param.pcb AND %00010000, NIL)
  1216.         outlist_i('\ebTMC:\en', param.pcb AND %00001100, NIL)
  1217.         outlist_i('\ebReserved:\en', param.pcb AND %00000010, NIL)
  1218.         outlist_i('\ebLP:\en', param.pcb AND %00000001, NIL)
  1219.         outlist_i('\ebParameter Length:\en', param.len, NIL)
  1220.         */
  1221.  
  1222.         plen:=param.len
  1223.         param:=param + (SIZEOF l_param)
  1224.  
  1225.         IF plen = 1
  1226.             outlist_i(buildstr, Char(param), NIL)
  1227.         ELSEIF plen = 2
  1228.             outlist_i(buildstr, Int(param), NIL)
  1229.         ELSEIF plen = 4
  1230.             outlist_i(buildstr, Long(param), NIL)
  1231.         ELSEIF plen = 8
  1232.             outlist_i(buildstr, Long(param), ' (Lower longword)')
  1233.             outlist_i(' ', Long(param+4), ' (Upper longword)')
  1234.         ELSE
  1235.             outlist(buildstr, 'Cannot Decode')
  1236.         ENDIF
  1237.  
  1238.         param:=param + plen
  1239.  
  1240.     ENDWHILE
  1241.  
  1242. ENDPROC
  1243.  
  1244. PROC process_log_buffer(reply:PTR TO l_sense)
  1245. DEF param:PTR TO lb_param
  1246.  
  1247.     ->outlist_i('\ebLog Size:\en', reply.len, ' bytes')
  1248.     outlist(' ', ' ')
  1249.     param:=reply + SIZEOF l_sense
  1250.  
  1251.     /*
  1252.     WHILE param < (reply + reply.len)
  1253.  
  1254.  
  1255.  
  1256.  
  1257.     ENDWHILE
  1258.     */
  1259. ENDPROC
  1260.  
  1261. PROC process_log_events(reply:PTR TO l_sense)
  1262.     outlist_i('\ebLog Size:\en', reply.len, ' bytes')
  1263.     outlist(' ', ' ')
  1264.  
  1265. ENDPROC
  1266.  
  1267.  
  1268.  
  1269.  
  1270.  
  1271. /*
  1272. ** Adds entries into the listview where both parameters are strings. The first
  1273. ** string is column one, the second is column two.
  1274. */
  1275. PROC outlist(str:PTR TO CHAR, str2:PTR TO CHAR)
  1276. DEF txt:listentry
  1277.  
  1278.     txt.field:=str
  1279.     txt.value:=str2
  1280.     txt.driver:=NIL
  1281.     txt.unit:=NIL
  1282.     doMethodA(mui_output_lst, [MUIM_List_InsertSingle, txt, MUIV_List_Insert_Bottom])
  1283. ENDPROC
  1284.  
  1285. /*
  1286. ** Adds entries into the listview where the first parameter is a string, the
  1287. ** second is an integer, and the third is an optional string. The first string
  1288. ** is column one, the integer is converted into a string and is column two.
  1289. ** In the case of the last string (if present) this is appended in column two
  1290. ** and is usually used for display a value type (eg bytes)
  1291. */
  1292. PROC outlist_i(str:PTR TO CHAR, int, valtype:PTR TO CHAR)
  1293. DEF txt:listentry,
  1294.     str2[80]:STRING
  1295.  
  1296.     IF valtype=NIL THEN StringF(str2, '\d', int) ELSE StringF(str2, '\d\s', int, valtype)
  1297.  
  1298.     txt.field:=str
  1299.     txt.value:=str2
  1300.     txt.driver:=NIL
  1301.     txt.unit:=NIL
  1302.     doMethodA(mui_output_lst, [MUIM_List_InsertSingle, txt, MUIV_List_Insert_Bottom])
  1303. ENDPROC
  1304.  
  1305. /*
  1306. ** Almost identical to outlist_i, except the integer is converted into Hex
  1307. ** before being made into a string
  1308. */
  1309. PROC outlist_h(str:PTR TO CHAR, int, valtype:PTR TO CHAR)
  1310. DEF txt:listentry,
  1311.     str2[80]:STRING
  1312.  
  1313.     IF valtype=NIL THEN StringF(str2, '$\h', int) ELSE StringF(str2, '$\h\s', int, valtype)
  1314.  
  1315.     txt.field:=str
  1316.     txt.value:=str2
  1317.     txt.driver:=NIL
  1318.     txt.unit:=NIL
  1319.     doMethodA(mui_output_lst, [MUIM_List_InsertSingle, txt, MUIV_List_Insert_Bottom])
  1320. ENDPROC
  1321.  
  1322. /*
  1323. ** This procedure adds special entries into the listview which the user may
  1324. ** double click. They have a specific format, with additional information
  1325. ** that is hidden from the display of the listview, but can be queried if
  1326. ** a user double clicks an entry.
  1327. */
  1328. PROC outlist_d(str:PTR TO CHAR, driver:PTR TO CHAR, unit)
  1329. DEF txt:listentry, buildstr[99]:STRING
  1330.  
  1331.     StringF(buildstr, '\eb\s [\d]:\en', driver, unit)
  1332.     txt.field:=buildstr
  1333.     txt.value:=str
  1334.     txt.driver:=driver
  1335.     txt.unit:=unit
  1336.     doMethodA(mui_output_lst, [MUIM_List_InsertSingle, txt, MUIV_List_Insert_Bottom])
  1337. ENDPROC
  1338.  
  1339. /*
  1340. ** The display hook for the listview. Entries are processed from an object
  1341. ** and insert into the appropriate columns
  1342. */
  1343. PROC disp(hook:PTR TO LONG, array:PTR TO LONG, entry:PTR TO listentry)
  1344.  
  1345.     IF entry=NIL -> MUI means update the titles whenever entry=NIL
  1346.         array[0]:='\eb\eu\ecField\en'
  1347.         array[1]:='\eb\eu\ecValue\en'
  1348.     ELSE
  1349.         array[0]:=entry.field
  1350.         array[1]:=entry.value
  1351.     ENDIF
  1352.  
  1353. ENDPROC 0
  1354.  
  1355. /*
  1356. ** The construction hook for the listview. Memory needs to be reserved
  1357. ** somewhere for each entry added, because only a pointer to a string actually
  1358. ** gets inserted. This copies each string into memory reserved from a pool. The
  1359. ** strings HAVE to be copied, as they will otherwise be freed by other
  1360. ** procedures, meaning the pointers in the listview would suddenly be invalid.
  1361. */
  1362. PROC construct (hook:PTR TO hook, pool:PTR TO LONG, obj:PTR TO listentry)
  1363. DEF value, field, driver=NIL, new:PTR TO listentry
  1364.  
  1365.     IF (field:=AllocPooled(pool, StrLen(obj.field)+1)) THEN CopyMem(obj.field, field, StrLen(obj.field)+1) -> +1 ensures NULL byte is copied
  1366.     IF (value:=AllocPooled(pool, StrLen(obj.value)+1)) THEN CopyMem(obj.value, value, StrLen(obj.value)+1) -> ditto
  1367.     IF obj.driver<>NIL
  1368.         IF (driver:=AllocPooled(pool, StrLen(obj.driver)+1)) THEN CopyMem(obj.driver, driver, StrLen(obj.driver)+1) -> ditto
  1369.     ENDIF
  1370.     new:=AllocPooled(pool, SIZEOF listentry)
  1371.     new.field:=field
  1372.     new.value:=value
  1373.     new.driver:=driver
  1374.     new.unit:=obj.unit
  1375. ENDPROC new
  1376.  
  1377. /*
  1378. ** Whenever an entry is removed from the listview, this procedure frees the
  1379. ** previously reserved memory for the strings.
  1380. */
  1381. PROC destruct (hook:PTR TO hook, pool:PTR TO LONG, obj:PTR TO listentry)
  1382.     FreePooled(pool, obj.field, StrLen(obj.field)+1)
  1383.     FreePooled(pool, obj.value, StrLen(obj.value)+1)
  1384.     IF obj.driver<>NIL THEN FreePooled(pool, obj.driver, StrLen(obj.driver)+1)
  1385.     FreePooled(pool, obj, SIZEOF listentry)
  1386. ENDPROC
  1387.  
  1388. /*
  1389. ** Simple macro procedure for making MUI buttons. Parameter 1 is the button
  1390. ** face, parameter 2 is the bubble help text. The buttons are automatically
  1391. ** added to the cycle chain
  1392. */
  1393. PROC make_button(face, bubble)
  1394. DEF button
  1395.  
  1396.     button:=SimpleButton(face)
  1397.     SetAttrsA(button, [MUIA_ShortHelp, bubble, MUIA_CycleChain, 1, TAG_DONE])
  1398. ENDPROC button
  1399.  
  1400. /*
  1401. ** Simple macro procedure for making cycle lists. Parameter 1 is an array of
  1402. ** the cycle contents, parameter 2 is the key which cycles it and parameter 3
  1403. ** is the bubble help test.
  1404. */
  1405. PROC make_keycycle(face, key, bubble)
  1406. DEF cycle
  1407.  
  1408.     cycle:=KeyCycle(face, key)
  1409.     SetAttrsA(cycle, [MUIA_ShortHelp, bubble, MUIA_CycleChain, 1, TAG_DONE])
  1410. ENDPROC cycle
  1411.  
  1412. /*
  1413. ** This procedure is called when the user double clicks and entry in the
  1414. ** listview. It queries the hidden data (as handled by outlist_d()) to
  1415. ** discover which device and unit to send the inquiry command to.
  1416. */
  1417. PROC click_inquiry()
  1418. DEF entry:PTR TO listentry, driver[99]:STRING, unit[4]:STRING
  1419.  
  1420.     doMethodA(mui_output_lst, [MUIM_List_GetEntry, MUIV_List_GetEntry_Active, {entry}])
  1421.     
  1422.     IF entry.driver <> NIL
  1423.         StrCopy(driver, entry.driver)
  1424.         StringF(unit, '\d', entry.unit)
  1425.         set(mui_device_tb, MUIA_String_Contents, driver)
  1426.         set(mui_unit_tb, MUIA_String_Contents, unit)
  1427.         doMethodA(mui_output_lst, [MUIM_List_Clear])
  1428.         query(driver, Val(unit), [SCSI_INQUIRY, 0, 0, 0, 36, 0]:cdb6, SIZEOF cdb6)=0
  1429.     ENDIF
  1430. ENDPROC
  1431.  
  1432. /*
  1433. ** Procedure to fill an array with device drivers from the execlist. The array
  1434. ** is used in the device driver poplist so the user can select one instead of
  1435. ** manually typing it.
  1436. */
  1437. PROC grab_devices()
  1438. DEF i=0, devnode:PTR TO ln, devlist:PTR TO lh, d[99]:STRING
  1439.  
  1440.     -> NOTE. This might need placing inside a Forbid()/Permit() pair but
  1441.     -> I'm not entirely certain about that.
  1442.     execobject:=execbase
  1443.     devlist:=execobject.devicelist
  1444.     devnode:=devlist.head
  1445.  
  1446.     WHILE devnode.succ
  1447.         StrCopy(d, devnode.name)
  1448.         IF StrCmp(d, 'audio.device')=TRUE           -> We only filter out
  1449.         ELSEIF StrCmp(d, 'audio.device')=TRUE       -> standard AmigaOS
  1450.         ELSEIF StrCmp(d, 'timer.device')=TRUE       -> drivers which are not
  1451.         ELSEIF StrCmp(d, 'gameport.device')=TRUE    -> appropriate because
  1452.         ELSEIF StrCmp(d, 'keyboard.device')=TRUE    -> filtering a large
  1453.         ELSEIF StrCmp(d, 'console.device')=TRUE     -> amount of drivers
  1454.         ELSEIF StrCmp(d, 'clipboard.device')=TRUE   -> would be expensive
  1455.         ELSEIF StrCmp(d, 'ramdrive.device')=TRUE    -> on slow CPUs.
  1456.         ELSEIF StrCmp(d, 'input.device')=TRUE
  1457.         ELSEIF StrCmp(d, 'trackdisk.device')=TRUE
  1458.         ELSEIF StrCmp(d, 'serial.device')=TRUE
  1459.         ELSEIF StrCmp(d, 'printer.device')=TRUE
  1460.         ELSEIF StrCmp(d, 'parallel.device')=TRUE
  1461.         ELSE
  1462.             devicelist[i]:=devnode.name
  1463.             i++
  1464.         ENDIF
  1465.         devnode:=devnode.succ
  1466.     ENDWHILE
  1467.     devicelist[i]:=NIL
  1468.  
  1469. ENDPROC
  1470.